
import 'package:flutter/material.dart';
import '../application.dart';
import '../utils/tools.dart';
import '../utils/api.dart';
import 'tags/divider.dart';
import 'tags/empty.dart';

abstract class ListPageState<T extends StatefulWidget, M> extends State<T> {
  ScrollController scrollController;

  bool gridMode = false;
  int gridCount = 2;
  double gridSpacing = 10;
  double gridAspectRatio = 0.8;

  int page = 1;
  bool hasMore = true;
  bool isLoading = true;
  List<M> lists = List();

  String apiUrl;
  String listKey = 'list';

  @override
  void initState() {
    super.initState();
    scrollController = ScrollController();
    scrollController.addListener(onScroll);
    loadData();
  }

  @override
  void dispose() {
    scrollController.dispose();
    if(lists != null)lists.clear();
    super.dispose();
  }

  onScroll() {
    if (!isLoading) {
      //print(_scrollController.position);
      if (hasMore &&
          scrollController.position.pixels + 10 >=
              scrollController.position.maxScrollExtent) {
        setState(() {
          isLoading = true;
        });
        page++;
        loadData();
      }
    }
  }

  ///TODO
  Widget buildSliver() {
    return CustomScrollView(
      slivers: <Widget>[],
    );
  }

  Widget buildList() {
    if (lists == null || lists.isEmpty) {
      if (isLoading) {
        return Center(
          child: CircularProgressIndicator(),
        );
      }
      return renderEmpty();
    }
    return ListView(
      controller: scrollController,
      children: <Widget>[
        SizedBox(
          height: 10,
        ),
        gridMode?buildGridView():buildListView(),
        renderMore()
      ],
    );
  }

  /// can override
  renderEmpty(){
    return TagEmpty('暂无数据');
  }

  /// can override
  renderMore() {
    return hasMore
        ? Container(
            height: 50,
            child: Center(
              child: SizedBox(
                  width: 20,
                  height: 20,
                  child: CircularProgressIndicator(
                    strokeWidth: 2,
                  )),
            ),
          )
        : TagDivider('没有更多了',);
  }

  buildGridView(){
    var width = (MediaQuery.of(context).size.width - gridSpacing * (gridCount+1))/gridCount;
    return Container(
      padding: EdgeInsets.all(gridSpacing),
      child: Wrap(
        runSpacing: gridSpacing,
        spacing: gridSpacing,
        children: lists.map<Widget>((item) {
          return buildItem(item,width:width);
        }).toList(),
      ),
    );
  }

  buildListView(){
    return Column(
      children: lists.map<Widget>((item) {
        return buildItem(item);
      }).toList(),
    );
  }

  /// override
  buildItem(M item,{double width});

  reload() {
    setState(() {
      lists.clear();
      page = 1;
      hasMore = true;
      isLoading = true;
    });
    loadData();
  }

  Map<String, dynamic> getParam(){
    return Map<String, dynamic>();
  }

  M transItem(dynamic item);

  /// override
  loadData() async{
    if(apiUrl == null || apiUrl.isEmpty){
      throw Exception('property apiUrl mast has a none empty value');
    }

    var param = getParam();
    param['page']=page;
    Api.post(apiUrl,param).then((result){
      //print(result);
      List<dynamic> list;
      if(result.data.containsKey(listKey) && result.data[listKey] is List){
        list = result.data[listKey];
      }
      if(list != null) {
        List<M> resultList = list.map<M>(transItem).toList();

        lists += resultList;
      }
      if(list == null || list.isEmpty ||
          (result.data.containsKey('pagesize') && list.length < Tools.parseInt(result.data['pagesize'])) ||
          (result.data.containsKey('total') && Tools.parseInt(result.data['total']) <= lists.length) ){
          hasMore = false;
      }
      setState(() {
        isLoading = false;
      });
    }).catchError((err){
      Application.toast('加载错误');
      isLoading = false;
    });
  }
}
